/*
 * @(#)WorkflowProcessor.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.workflow.core;

import java.sql.Connection;
import java.sql.SQLException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.DataSourceFactory;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.workflow.bean.WorkflowProgress;

/**
 * WorkflowProcessor.java
 *
 * This class is responsible for workflow automatic task processor.
 *
 * @author          Rollo Chan
 * @company         DCIVision Limited
 * @creation date   24/10/2003
 * @version         $Revision: 1.16.2.1 $
 */

public abstract class WorkflowProcessor {
  public final static int LABEL_TYPE_APPROVAL = 0;
  public final static int LABEL_TYPE_YES_NO = 1;
  public final static int LABEL_TYPE_USER_DEFINE = 2;

  protected Log log = LogFactory.getLog(this.getClass().getName());

  /** Defines whether to automatically execute next step after this task is completed */
  protected boolean bAutoExecuteNextStep = false;
  /** Defines whether to create a workflow progress object for next step after this task is completed */
  protected boolean bCreateNextWorkflowProgress = true;
  /** Defines whether this task is parent dependent, if yes, will wake up the parent */
  protected boolean parentDependent = false;
  /** Defines the status for this task after completed */
  protected String currentProgressStatus = WorkflowProgress.STATUS_GENERAL_ACCOMPLISHMENT;
  /** Defines the number of routine of this task */
  protected int numOfRoutine = 1;
  /** Defines which routine this task will follow after completed */
  protected int returnRoutineIndex = 0;
  /** Defines the label of the routine */
  protected int labelType = LABEL_TYPE_APPROVAL;
  /** Defines the label (in ApplicationResources.properties) */
  protected String[] labelString = new String[] { "workflow.label.step_status_R", "workflow.label.step_status_A" };
  protected String[] parameterNames=null;//added by nancy

  /**Defines the workflow step have not child step  */
  protected boolean isLeaf = false;
  protected Connection connection = null;
  protected boolean isLocalConnection = false;

  /** The actual method for completing the workflow progress */
  public abstract void execute(org.quartz.JobDataMap jobDataMap, com.dcivision.workflow.bean.WorkflowProgress currentProgress) throws ApplicationException;
  public void setConnection(Connection conn){
    isLocalConnection = false;
    this.connection = conn;
  }

  public Connection getConnection() throws Exception{
    if(connection==null){
       connection = DataSourceFactory.getConnection();
       isLocalConnection = true;
    }
    return connection;
  }

  public void closeConnection(Connection conn){
    //only close the connection if this connection reference is not passed from caller
    if(isLocalConnection && conn != null){
      try { conn.close(); } catch (Exception ignore) {} finally { conn = null; }
    }
  }

  public void commitConnection(Connection conn) throws SQLException{
    //only close the connection if this connection reference is not passed from caller
    if(isLocalConnection && conn != null) {
      conn.commit();
    }
  }
  //added by nancy

  public void rollbackConnection(Connection conn)throws SQLException{
    if(isLocalConnection && conn != null) {
      conn.rollback();
    }
  }
  //added by tc
  
  /**
   * @return string[] The object of all parameter names
   */
  public String[] getParameterNames(){
    if(Utility.isEmpty(this.parameterNames)){
      return new String[]{};
    }
    else{
      return (this.parameterNames);
    }
  }
  //end
  /**
   * @return int The number of routine
   */
  public int getNumOfRoutine() {
    return (Math.min(this.numOfRoutine, this.labelString.length));
  }
  /**
   *
   * @return int The result routine
   */
  public int getResultRoutine() {
    return (this.returnRoutineIndex);
  }
  /**
   *
   * @return Returns The bAutoExecuteNextStep
   */
  public boolean isAutoExecuteNextStep() {
    return (this.bAutoExecuteNextStep);
  }
  /**
   *
   * @return Returns The bCreateNextWorkflowProgress
   */
  public boolean isCreateNextWorkflowProgress() {
    return (this.bCreateNextWorkflowProgress);
  }
  /**
   *
   * @return Returns The currentProgressStatus
   */
  public String getCurrentProgressStatus() {
    return (this.currentProgressStatus);
  }
  /**
   *
   * @return Returns The labelType
   */
  public int getLabelType() {
    return (this.labelType);
  }

  public String getLabelString(String index) {
    return getLabelString(TextUtility.parseInteger(index));
  }

  public String getLabelString(int index) {
    if (index < labelString.length) {
      return (this.labelString[index]);
    } else {
      return "invalid status";
    }
  }
  /**
   * @return SessionContainer The new SessionContainer at this moment, will evaluate again on what should return
   */
  public SessionContainer getSessionContainer() {
    SessionContainer sessionCon = new SessionContainer();
    return sessionCon;
  }

  public boolean isLeaf() {
    return (this.isLeaf);
  }
}
